<template>
  <div>
    <div class="video-call-container" v-if="isVisible">
      <div class="video-call-header">
        <h3>视频通话</h3>
        <div class="call-status">
          {{ callStatusText }}
          <span v-if="remoteScreenSharing" class="screen-share-indicator">对方正在分享屏幕</span>
        </div>
        <button class="close-btn" @click="handleHangup">
          <img :src="hangupIcon" alt="Close" class="hangup-icon">
        </button>
      </div>
      
      <div class="video-container">
        <!-- 远程视频 -->
        <div class="remote-video-container">
          <video ref="remoteVideo" class="remote-video" autoplay playsinline></video>
          <div class="no-remote-video" v-if="!hasRemoteVideo">
            <div class="avatar">{{ friendInitial }}</div>
            <div class="connecting-text">{{ connectingText }}</div>
          </div>
        </div>
        
        <!-- 本地视频 -->
        <div class="local-video-container">
          <video ref="localVideo" class="local-video" autoplay playsinline muted></video>
        </div>
      </div>
      
      <div class="call-controls">
        <button 
          class="control-btn mute-btn" 
          :class="{ active: isAudioMuted }"
          @click="toggleAudio"
        >
          <img :src="isAudioMuted ? speakerMutedIcon : speakerIcon" alt="Mute" class="icon">
        </button>
        
        <button 
          class="control-btn video-btn" 
          :class="{ active: isVideoOff }"
          @click="toggleVideo"
        >
          <img :src="isVideoOff ? cameraOffIcon : cameraIcon" alt="Video" class="icon">
        </button>
        
        <button 
          class="control-btn screen-share-btn" 
          :class="{ active: isScreenSharing }"
          @click="toggleScreenShare"
          :disabled="callStatus !== 'connected'"
        >
          <img :src="isScreenSharing ? screenShareIcon : screenShareOffIcon" alt="Screen Share" class="icon">
        </button>
        
        <button class="control-btn hangup-btn" @click="handleHangup">
          <img :src="hangupIcon" alt="Hangup" class="icon">
        </button>
      </div>
    </div>
    
    <!-- 来电提示 -->
    <div class="incoming-call-dialog" v-if="showIncomingCall">
      <div class="dialog-content">
        <h3>来电</h3>
        <p>{{ callerName }} 正在呼叫您</p>
        <div class="dialog-buttons">
          <button class="accept-btn" @click="acceptIncomingCall">接听</button>
          <button class="reject-btn" @click="rejectIncomingCall">拒绝</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, computed, watch } from 'vue';
import * as webrtc from '@/utils/webrtc';
import speakerIcon from '@/assets/扬声器.png';
import speakerMutedIcon from '@/assets/关闭扬声器.png';
import cameraIcon from '@/assets/摄像头.png';
import cameraOffIcon from '@/assets/摄像头_关闭.png';
import screenShareIcon from '@/assets/屏幕共享1.png';
import screenShareOffIcon from '@/assets/屏幕共享关.png';
import hangupIcon from '@/assets/挂断.png';

const props = defineProps({
  isVisible: {
    type: Boolean,
    default: false
  },
  friendId: {
    type: String,
    required: true
  },
  friendName: {
    type: String,
    default: '好友'
  },
  userId: {
    type: String,
    required: true
  },
  isIncoming: {
    type: Boolean,
    default: false
  },
  offerData: {
    type: String,
    default: ''
  }
});

const emit = defineEmits(['close', 'callStarted', 'callEnded']);

// 视频元素引用
const localVideo = ref(null);
const remoteVideo = ref(null);

// 通话状态
const callStatus = ref('initializing'); // initializing, connecting, connected, ended
const isAudioMuted = ref(false);
const isVideoOff = ref(false);
const hasRemoteVideo = ref(false);
const showIncomingCall = ref(false);
const isScreenSharing = ref(false);
const remoteScreenSharing = ref(false);

// 计算属性
const callStatusText = computed(() => {
  switch (callStatus.value) {
    case 'initializing':
      return '初始化中...';
    case 'connecting':
      return '正在连接...';
    case 'connected':
      return '已连接';
    case 'ended':
      return '通话已结束';
    default:
      return '';
  }
});

const connectingText = computed(() => {
  return callStatus.value === 'connecting' ? '正在连接...' : '等待对方接听...';
});

const friendInitial = computed(() => {
  return props.friendName ? props.friendName.charAt(0).toUpperCase() : '?';
});

const callerName = computed(() => {
  return props.friendName || '好友';
});

// 初始化WebRTC
onMounted(() => {
  console.log('VideoCall组件挂载，初始化WebRTC');
  webrtc.initWebRTC(props.userId);
  
  // 设置事件处理器
  webrtc.setEventHandlers({
    onCallStarted: () => {
      console.log('通话已开始');
      callStatus.value = 'connected';
      emit('callStarted');
    },
    onCallEnded: () => {
      console.log('通话已结束');
      callStatus.value = 'ended';
      emit('callEnded');
      emit('close');
    },
    onError: handleError,
    onRemoteStream: (stream) => {
      console.log('收到远程流');
      if (remoteVideo.value) {
        remoteVideo.value.srcObject = stream;
        hasRemoteVideo.value = true;
      }
    },
    onLocalStream: (stream) => {
      console.log('获取本地流');
      if (localVideo.value) {
        localVideo.value.srcObject = stream;
      }
    },
    onScreenShare: handleScreenShareStarted,
    onScreenShareEnded: handleScreenShareEnded,
    onRemoteScreenShare: (isSharing) => {
      remoteScreenSharing.value = isSharing;
    }
  });
  
  // 如果是接收方，显示来电提示
  if (props.isIncoming && props.offerData) {
    console.log('收到来电，显示来电提示');
    showIncomingCall.value = true;
  } else if (props.isVisible && !props.isIncoming) {
    // 如果是发起方，直接开始通话
    console.log('发起通话');
    startCall();
  }
});

// 组件卸载时清理资源
onUnmounted(() => {
  webrtc.endCall();
  
  // 清理屏幕分享
  if (isScreenSharing.value) {
    webrtc.stopScreenShare();
  }
});

// 监听属性变化
watch(() => props.isVisible, (newValue) => {
  if (newValue && !props.isIncoming) {
    startCall();
  }
});

// 开始通话
const startCall = async () => {
  try {
    // 先检查设备权限
    await checkDevicePermissions();
    
    callStatus.value = 'connecting';
    const success = await webrtc.startCall(props.friendId);
    if (!success) {
      callStatus.value = 'ended';
      setTimeout(() => {
        emit('close');
      }, 2000);
    }
  } catch (error) {
    console.error('开始通话前检查设备权限失败:', error);
    handleError(new Error('无法访问摄像头或麦克风，请检查设备权限'));
  }
};

// 接受来电
const acceptIncomingCall = async () => {
  try {
    // 先检查设备权限
    await checkDevicePermissions();
    
    showIncomingCall.value = false;
    callStatus.value = 'connecting';
    const success = await webrtc.acceptCall(props.offerData, props.friendId);
    if (!success) {
      callStatus.value = 'ended';
      setTimeout(() => {
        emit('close');
      }, 2000);
    }
  } catch (error) {
    console.error('接受通话前检查设备权限失败:', error);
    showIncomingCall.value = false;
    handleError(new Error('无法访问摄像头或麦克风，请检查设备权限'));
  }
};

// 拒绝来电
const rejectIncomingCall = () => {
  showIncomingCall.value = false;
  emit('close');
};

// 处理错误
const handleError = (error) => {
  console.error('视频通话错误:', error);
  
  // 根据错误类型显示不同的错误消息
  let errorMessage = '视频通话出现错误';
  
  if (error.message && error.message.includes('Device in use')) {
    errorMessage = '摄像头或麦克风正被其他应用程序使用，请关闭其他使用摄像头的应用后重试';
  } else if (error.name === 'NotAllowedError' || (error.message && error.message.includes('Permission denied'))) {
    errorMessage = '请允许浏览器访问您的摄像头和麦克风';
  } else if (error.name === 'NotFoundError' || (error.message && error.message.includes('未找到'))) {
    errorMessage = '未找到摄像头或麦克风设备';
  } else if (error.name === 'NotReadableError') {
    errorMessage = '无法读取摄像头或麦克风，设备可能被占用';
  }
  
  // 只有在通话已经开始的情况下才显示错误并结束通话
  if (callStatus.value === 'connected' || callStatus.value === 'connecting') {
    callStatus.value = 'ended';
    hasRemoteVideo.value = false;
    
    // 显示错误提示
    alert(errorMessage);
    
    // 延迟关闭组件
    setTimeout(() => {
      emit('close');
    }, 2000);
  } else if (callStatus.value === 'initializing') {
    // 如果在初始化阶段出错，也需要关闭组件
    callStatus.value = 'ended';
    
    // 显示错误提示
    alert(errorMessage);
    
    // 延迟关闭组件
    setTimeout(() => {
      emit('close');
    }, 1000);
  }
  
  // 触发通话结束事件
  emit('callEnded');
};

// 切换音频
const toggleAudio = () => {
  const stream = localVideo.value?.srcObject;
  if (stream) {
    const audioTracks = stream.getAudioTracks();
    audioTracks.forEach(track => {
      track.enabled = !track.enabled;
    });
    isAudioMuted.value = !audioTracks[0]?.enabled;
  }
};

// 切换视频
const toggleVideo = () => {
  const stream = localVideo.value?.srcObject;
  if (stream) {
    const videoTracks = stream.getVideoTracks();
    videoTracks.forEach(track => {
      track.enabled = !track.enabled;
    });
    isVideoOff.value = !videoTracks[0]?.enabled;
  }
};

// 切换屏幕分享
const toggleScreenShare = async () => {
  try {
    if (isScreenSharing.value) {
      // 停止屏幕分享
      await webrtc.stopScreenShare();
      isScreenSharing.value = false;
    } else {
      // 开始屏幕分享
      const success = await webrtc.startScreenShare();
      isScreenSharing.value = success;
    }
  } catch (error) {
    console.error('切换屏幕分享时出错:', error);
    handleError(error);
  }
};

// 处理屏幕分享开始
const handleScreenShareStarted = (stream) => {
  console.log('屏幕分享已开始');
  isScreenSharing.value = true;
};

// 处理屏幕分享结束
const handleScreenShareEnded = () => {
  console.log('屏幕分享已结束');
  isScreenSharing.value = false;
};

// 挂断通话
const handleHangup = () => {
  webrtc.endCall();
};

// 检查设备权限
const checkDevicePermissions = async () => {
  try {
    // 检查是否有可用的摄像头和麦克风
    const devices = await navigator.mediaDevices.enumerateDevices();
    const hasVideoInput = devices.some(device => device.kind === 'videoinput');
    const hasAudioInput = devices.some(device => device.kind === 'audioinput');
    
    if (!hasVideoInput && !hasAudioInput) {
      throw new Error('未检测到摄像头和麦克风设备');
    }
    
    if (!hasVideoInput) {
      console.warn('未检测到摄像头设备，将使用纯音频模式');
    }
    
    if (!hasAudioInput) {
      throw new Error('未检测到麦克风设备，无法进行通话');
    }
    
    return true;
  } catch (error) {
    console.error('检查设备权限失败:', error);
    throw error;
  }
};
</script>

<style scoped>
.video-call-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: #000;
  z-index: 1000;
  display: flex;
  flex-direction: column;
}

.video-call-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 15px;
  background-color: rgba(0, 0, 0, 0.7);
  color: white;
}

.close-btn {
  background: none;
  border: none;
  color: white;
  font-size: 24px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.hangup-icon {
  width: 24px;
  height: 24px;
  object-fit: contain;
}

.video-container {
  flex: 1;
  position: relative;
  overflow: hidden;
}

.remote-video-container {
  width: 100%;
  height: 100%;
  background-color: #222;
  display: flex;
  justify-content: center;
  align-items: center;
}

.remote-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.no-remote-video {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: white;
}

.avatar {
  width: 120px;
  height: 120px;
  border-radius: 50%;
  background-color: #4caf50;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 60px;
  margin-bottom: 20px;
}

.connecting-text {
  font-size: 18px;
  color: #ccc;
}

.local-video-container {
  position: absolute;
  bottom: 20px;
  right: 20px;
  width: 150px;
  height: 200px;
  border-radius: 8px;
  overflow: hidden;
  border: 2px solid white;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
}

.local-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.call-controls {
  display: flex;
  justify-content: center;
  padding: 20px;
  background-color: rgba(0, 0, 0, 0.7);
}

.control-btn {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  margin: 0 10px;
  border: none;
  background-color: #444;
  color: white;
  font-size: 20px;
  cursor: pointer;
  display: flex;
  justify-content: center;
  align-items: center;
}

.control-btn.active {
  background-color: #f44336;
}

.control-btn.video-btn.active {
  background-color: #ff5252;
}

.control-btn.screen-share-btn {
  background-color: #4caf50;
}

.control-btn.screen-share-btn.active {
  background-color: #2196f3;
}

.control-btn.screen-share-btn:disabled {
  background-color: #cccccc;
  cursor: not-allowed;
}

.control-btn.hangup-btn {
  background-color: #f44336;
}

.icon {
  font-style: normal;
  width: 24px;
  height: 24px;
  object-fit: contain;
}

.incoming-call-dialog {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.7);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1001;
}

.dialog-content {
  background-color: white;
  padding: 20px;
  border-radius: 8px;
  width: 300px;
  text-align: center;
}

.dialog-buttons {
  display: flex;
  justify-content: space-around;
  margin-top: 20px;
}

.accept-btn, .reject-btn {
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.accept-btn {
  background-color: #4caf50;
  color: white;
}

.reject-btn {
  background-color: #f44336;
  color: white;
}

.screen-share-indicator {
  font-size: 12px;
  color: #4caf50;
  margin-left: 5px;
}
</style> 